package com.oauth.linkedin.server.util;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.EnumSet;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;

import com.google.code.linkedinapi.client.enumeration.NetworkUpdateType;
import com.google.code.linkedinapi.schema.Connections;
import com.google.code.linkedinapi.schema.DateOfBirth;
import com.google.code.linkedinapi.schema.Person;
import com.google.code.linkedinapi.schema.Update;
import com.google.code.linkedinapi.schema.Updates;
import com.oauth.linkedin.client.beans.LinkedinUser;
import com.oauth.service.application.global.beans.Birthday;

public class LinkedinUtil {

	public static EnumSet<NetworkUpdateType> updatesSet = EnumSet.of(
			NetworkUpdateType.STATUS_UPDATE,
			/*
			 * NetworkUpdateType.CONNECTION_UPDATE,
			 * NetworkUpdateType.JOB_UPDATE,
			 */NetworkUpdateType.PROFILE_UPDATE, NetworkUpdateType.RECOMMENDATION_UPDATE);

	public static List<LinkedinUser> getUsers(Connections pConnections) {
		List<LinkedinUser> users = new ArrayList<LinkedinUser>();
		if (pConnections != null) {
			for (Person person : pConnections.getPersonList()) {
				users.add(getUser(person));
			}
		}
		return users;
	}

	public static List<Birthday> getBirthdays(Connections pConnections, int pBirthdayInterval) {
		List<Birthday> birthdayList = new ArrayList<Birthday>();
		if (pConnections != null) {

			Calendar current = Calendar.getInstance();
			Calendar future = getFuture(pBirthdayInterval);

			for (Person person : pConnections.getPersonList()) {
				Birthday birthday = getBirthday(person, current, future);
				if (birthday != null) {
					birthdayList.add(birthday);
					System.out.println(birthday);
				}
			}
		}
		return birthdayList;
	}

	private static Birthday getBirthday(Person pPerson, Calendar current, Calendar future) {
		DateOfBirth dob = pPerson.getDateOfBirth();
		Calendar birthCalendar = getBirthCalendar(dob);
		if (birthCalendar == null) {
			return null;
		}
		String birthString = isValid(birthCalendar, current, future);
		if (birthString == null) {
			return null;
		}
		Birthday birthday = new Birthday();
		birthday.setDisplayName(pPerson.getFirstName() + " " + pPerson.getLastName());
		birthday.setPictureUrl(pPerson.getPictureUrl());
		birthday.setProfileUrl(pPerson.getPublicProfileUrl());
		birthday.setBirthDay(birthString);
		return birthday;
	}

	private static Calendar getBirthCalendar(DateOfBirth dob) {
		if (dob == null) {
			return null;
		}
		if (dob.getYear() == null) {
			dob.setYear(2000L);
		}
		try {
			return new GregorianCalendar(dob.getYear().intValue(), dob.getMonth().intValue() - 1,
					dob.getDay().intValue());
		} catch (Exception e) {
			return null;
		}
	}

	private static Calendar getFuture(int pBirthdayInterval) {
		Calendar future = Calendar.getInstance();
		future.add(Calendar.DAY_OF_MONTH, pBirthdayInterval);
		return future;
	}

	private static String isValid(Calendar birth, Calendar current, Calendar future) {
		int currMonth = current.get(Calendar.MONTH);
		int birthMonth = birth.get(Calendar.MONTH);

		int currDay = current.get(Calendar.DAY_OF_MONTH);
		int birthDay = birth.get(Calendar.DAY_OF_MONTH);

		if (currMonth == birthMonth) {
			if (birthDay == currDay) {
				return getBirthString(birth) + Birthday.TODAY;
			}
			if (birthDay == (currDay + 1)) {
				return getBirthString(birth) + Birthday.TOMORROW;
			}
			if (birthDay > currDay) {
				return getBirthString(birth);
			}
		} else if ((currMonth == 11 && birthMonth == 0) || ((currMonth + 1) == birthMonth)) {
			if (birthDay <= future.get(Calendar.DAY_OF_MONTH)) {
				return getBirthString(birth);
			}
		}
		return null;
	}

	private static String getBirthString(Calendar birth) {
		return birth.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.US) + " "
				+ birth.get(Calendar.DAY_OF_MONTH);
	}

	public static List<LinkedinUser> getUpdates(Updates pUpdates) {
		List<LinkedinUser> users = new ArrayList<LinkedinUser>();
		if (pUpdates != null) {
			for (Update update : pUpdates.getUpdateList()) {
				users.add(getUser(update.getUpdateContent().getPerson()));
				System.out.println("key=" + update.getUpdateKey());
			}
		}
		return users;
	}

	public static LinkedinUser getUser(Person profile) {
		LinkedinUser user = new LinkedinUser();
		user.setFirstName(profile.getFirstName());
		user.setLastName(profile.getLastName());
		user.setHeadLine(profile.getHeadline());
		user.setId(profile.getId());
		user.setProfileImageUrl(profile.getPictureUrl());
		user.setStatus(profile.getCurrentStatus());
		System.out.println(user);
		return user;
	}

}
